#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
高德地图 REST API 服务（备用方案）
使用高德传统REST API实现地图功能
这是MCP服务的替代方案，可以立即使用
"""

import json
import requests
from typing import Dict, Any, Optional, List


class AmapRestService:
    """高德地图REST API服务客户端"""
    
    def __init__(self, api_key: str):
        """
        初始化REST API服务
        
        Args:
            api_key: 高德地图API Key
        """
        self.api_key = api_key
        self.base_url = "https://restapi.amap.com"
        self.session = requests.Session()
        self.connected = True
        
        print(f"📍 初始化高德地图REST API服务 (API Key: {api_key[:8]}...)")
    
    def _request(self, endpoint: str, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        发送API请求
        
        Args:
            endpoint: API端点
            params: 请求参数
            
        Returns:
            响应数据
        """
        try:
            # 添加API Key
            params['key'] = self.api_key
            
            url = f"{self.base_url}{endpoint}"
            response = self.session.get(url, params=params, timeout=10)
            
            if response.status_code != 200:
                return {
                    'success': False,
                    'error': f'HTTP错误: {response.status_code}',
                    'data': None
                }
            
            data = response.json()
            
            # 检查API响应状态
            if data.get('status') == '1':
                return {
                    'success': True,
                    'data': data,
                    'raw': data
                }
            else:
                error_msg = data.get('info', '未知错误')
                return {
                    'success': False,
                    'error': f'API错误: {error_msg} (错误码: {data.get("infocode")})',
                    'data': data
                }
                
        except requests.exceptions.RequestException as e:
            return {
                'success': False,
                'error': f'网络请求失败: {str(e)}',
                'data': None
            }
        except Exception as e:
            return {
                'success': False,
                'error': f'处理失败: {str(e)}',
                'data': None
            }
    
    # ========== 天气查询 ==========
    
    def get_weather(self, city: str, extensions: str = 'base') -> Dict[str, Any]:
        """
        查询天气信息
        
        Args:
            city: 城市名称或城市编码
            extensions: base=实况天气, all=预报天气
            
        Returns:
            天气信息
        """
        print(f"🌤️  查询天气: {city}")
        
        # 如果是城市名，先获取城市编码
        if not city.isdigit():
            city_code = self._get_city_code(city)
            if not city_code:
                return {
                    'success': False,
                    'error': f'未找到城市: {city}',
                    'data': None
                }
            city = city_code
        
        result = self._request('/v3/weather/weatherInfo', {
            'city': city,
            'extensions': extensions
        })
        
        if result['success']:
            print(f"✅ 天气查询成功")
        else:
            print(f"❌ 查询失败: {result['error']}")
        
        return result
    
    def _get_city_code(self, city_name: str) -> Optional[str]:
        """
        获取城市编码
        
        Args:
            city_name: 城市名称
            
        Returns:
            城市编码或None
        """
        # 常用城市编码映射
        city_codes = {
            '北京': '110000', '上海': '310000', '天津': '120000', '重庆': '500000',
            '广州': '440100', '深圳': '440300', '成都': '510100', '杭州': '330100',
            '武汉': '420100', '西安': '610100', '郑州': '410100', '南京': '320100',
            '济南': '370100', '沈阳': '210100', '青岛': '370200', '长沙': '430100',
            '哈尔滨': '230100', '昆明': '530100', '兰州': '620100', '苏州': '320500',
            '大连': '210200', '厦门': '350200', '合肥': '340100', '石家庄': '130100',
            '福州': '350100', '南昌': '360100', '长春': '220100', '贵阳': '520100',
            '太原': '140100', '南宁': '450100', '乌鲁木齐': '650100', '海口': '460100',
        }
        
        return city_codes.get(city_name)
    
    # ========== POI搜索 ==========
    
    def search_poi(self, keywords: str, city: Optional[str] = None, 
                   types: Optional[str] = None, page_size: int = 10) -> Dict[str, Any]:
        """
        搜索地点（POI）
        
        Args:
            keywords: 搜索关键词
            city: 城市名称（可选）
            types: POI类型（可选）
            page_size: 每页结果数（默认10）
            
        Returns:
            搜索结果
        """
        print(f"🔍 搜索POI: {keywords}" + (f" (城市: {city})" if city else ""))
        
        params = {
            'keywords': keywords,
            'offset': page_size
        }
        
        if city:
            params['city'] = city
        if types:
            params['types'] = types
        
        result = self._request('/v3/place/text', params)
        
        if result['success']:
            pois = result['data'].get('pois', [])
            print(f"✅ 搜索成功，找到 {len(pois)} 个结果")
        else:
            print(f"❌ 搜索失败: {result['error']}")
        
        return result
    
    # ========== 路线规划 ==========
    
    def plan_route(self, origin: str, destination: str, 
                  mode: str = 'driving', city: Optional[str] = None) -> Dict[str, Any]:
        """
        规划路线
        
        Args:
            origin: 起点（地名或经纬度）
            destination: 终点（地名或经纬度）
            mode: 出行方式（driving/walking/transit/riding）
            city: 城市（可选，地名转坐标时使用）
            
        Returns:
            路线规划结果
        """
        print(f"🚗 规划路线: {origin} → {destination} ({mode})")
        
        # 转换地名为坐标
        origin_location = self._name_to_location(origin, city)
        dest_location = self._name_to_location(destination, city)
        
        if not origin_location:
            return {
                'success': False,
                'error': f'无法找到起点"{origin}"，请确认地点名称是否正确',
                'data': None
            }
        
        if not dest_location:
            return {
                'success': False,
                'error': f'无法找到终点"{destination}"，请确认地点名称是否正确',
                'data': None
            }
        
        # 根据出行方式选择API
        mode_map = {
            'driving': '/v3/direction/driving',
            'walking': '/v3/direction/walking',
            'transit': '/v5/direction/transit/integrated',
            'riding': '/v4/direction/bicycling'
        }
        
        endpoint = mode_map.get(mode, '/v3/direction/driving')
        
        params = {
            'origin': origin_location,
            'destination': dest_location
        }
        
        if mode == 'transit' and city:
            params['city'] = city
        
        result = self._request(endpoint, params)
        
        if result['success']:
            print(f"✅ 路线规划成功")
        else:
            print(f"❌ 规划失败: {result['error']}")
        
        return result
    
    # ========== 地理编码 ==========
    
    def geocode(self, address: str, city: Optional[str] = None) -> Dict[str, Any]:
        """
        地理编码（地址转坐标）
        
        Args:
            address: 地址
            city: 城市（可选）
            
        Returns:
            坐标信息
        """
        print(f"📍 地址编码: {address}")
        
        params = {'address': address}
        if city:
            params['city'] = city
        
        result = self._request('/v3/geocode/geo', params)
        return result
    
    def reverse_geocode(self, location: str) -> Dict[str, Any]:
        """
        逆地理编码（坐标转地址）
        
        Args:
            location: 经纬度（格式：经度,纬度）
            
        Returns:
            地址信息
        """
        print(f"📍 坐标解析: {location}")
        
        result = self._request('/v3/geocode/regeo', {
            'location': location
        })
        
        if result['success']:
            print(f"✅ 解析成功")
        else:
            print(f"❌ 解析失败: {result['error']}")
        
        return result
    
    def _name_to_location(self, name: str, city: Optional[str] = None) -> Optional[str]:
        """
        地名转坐标（增强版：支持地理编码+POI搜索）
        
        Args:
            name: 地名或POI名称
            city: 城市
            
        Returns:
            经纬度字符串或None
        """
        # 如果已经是坐标格式，直接返回
        if ',' in name and all(p.replace('.', '').replace('-', '').isdigit() for p in name.split(',')):
            return name
        
        # 方法1: 先尝试地理编码（适合地址）
        result = self.geocode(name, city)
        if result['success']:
            geocodes = result['data'].get('geocodes', [])
            if geocodes:
                location = geocodes[0].get('location')
                print(f"✅ 编码成功（地理编码）: {name} → {location}")
                return location
        
        # 方法2: 如果地理编码失败，尝试POI搜索（适合公司名、景点名等）
        print(f"⚠️  地理编码失败，尝试POI搜索: {name}")
        search_result = self.search_poi(keywords=name, city=city, page_size=1)
        
        if search_result['success']:
            pois = search_result['data'].get('pois', [])
            if pois:
                location = pois[0].get('location')
                poi_name = pois[0].get('name')
                print(f"✅ 编码成功（POI搜索）: {name} → {poi_name} ({location})")
                return location
        
        print(f"❌ 编码失败: 无法找到地点 {name}")
        return None
    
    # ========== 周边搜索 ==========
    
    def search_around(self, location: str, keywords: str, 
                     radius: int = 1000, page_size: int = 10) -> Dict[str, Any]:
        """
        周边搜索
        
        Args:
            location: 中心点坐标（经度,纬度）
            keywords: 搜索关键词
            radius: 搜索半径（米，默认1000）
            page_size: 每页结果数
            
        Returns:
            搜索结果
        """
        print(f"🔍 周边搜索: {keywords} (半径: {radius}m)")
        
        result = self._request('/v3/place/around', {
            'location': location,
            'keywords': keywords,
            'radius': radius,
            'offset': page_size
        })
        
        if result['success']:
            pois = result['data'].get('pois', [])
            print(f"✅ 找到 {len(pois)} 个结果")
        else:
            print(f"❌ 搜索失败: {result['error']}")
        
        return result
    
    # ========== 距离计算 ==========
    
    def calculate_distance(self, origins: List[str], destination: str,
                          type_: int = 1) -> Dict[str, Any]:
        """
        计算距离
        
        Args:
            origins: 起点列表（经纬度）
            destination: 终点（经纬度）
            type_: 计算类型（1=直线距离，0=驾车距离）
            
        Returns:
            距离信息
        """
        print(f"📏 计算距离: {len(origins)}个起点 → 终点")
        
        result = self._request('/v3/distance', {
            'origins': '|'.join(origins),
            'destination': destination,
            'type': type_
        })
        
        if result['success']:
            print(f"✅ 计算成功")
        else:
            print(f"❌ 计算失败: {result['error']}")
        
        return result
    
    # ========== 工具方法 ==========
    
    def get_status(self) -> Dict[str, Any]:
        """获取服务状态"""
        return {
            'connected': self.connected,
            'api_key_configured': bool(self.api_key),
            'service_type': 'REST API',
            'base_url': self.base_url
        }
    
    def disconnect(self):
        """断开连接"""
        try:
            self.session.close()
            self.connected = False
            print("🔌 已断开连接")
        except Exception as e:
            print(f"⚠️  断开连接时出错: {str(e)}")


# ========== 便捷函数 ==========

def create_amap_rest_service(api_key: str) -> AmapRestService:
    """
    创建高德地图REST API服务实例
    
    Args:
        api_key: 高德地图API Key
        
    Returns:
        AmapRestService实例
    """
    return AmapRestService(api_key)

